﻿#include "Core/MainWindow.h"

#include <QVBoxLayout>
#include <vtkNew.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <IVtkTools_ShapeDataSource.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <vtkProperty.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkRenderer.h>
#include "Widget/Solid/CreateCubeWidget.h"
#include <BRepPrimAPI_MakeSphere.hxx>
#include "Widget/Solid/CreateSphereWidget.h"
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepPrimAPI_MakeCone.hxx>
#include <BRepPrimAPI_MakeTorus.hxx>
#include <vtkLine.h>
#include <vtkInteractorStyleTrackballCamera.h>

#include "Widget/Solid/CreateCylinderWidget.h"
#include "Widget/Solid/CreateTorusWidget.h"
#include "Widget/Solid/CreateConeWidget.h"
#include "Widget/Curve/CreateLineWidget.h"
#include "Render/WindowInteractor.h"
#include "Render/WindowInteractorStyle.h"
#include "vtkPropPicker.h"
#include <algorithm>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include "RWTools.h"
#include <BRepBuilderAPI_Transform.hxx>
#include "Widget/Operation/BooleanOperationWidget.h"
#include <BRepAlgoAPI_Common.hxx>
#include <BRepAlgoAPI_Cut.hxx>
#include <BRepAlgoAPI_Fuse.hxx>
#include "Render/vtkTipsCoordinate.h"
#include "Widget/Operation/TransformOperationWidget.h"
#include "Widget/Operation/StretchOperationWidget.h"
#include "Widget/Operation/RevolveOperationWidget.h"
#include "Widget/Operation/RoundOffOperationWidget.h"
#include "Widget/Operation/HollowOperationWidget.h"
#include "Widget/Operation/QFillOperationWidget.h"
#include "Widget/Curve/CreatCircleWidget.h"
#include <GC_MakeArcOfCircle.hxx>
#include "Widget/Curve/CreateEllipseWidget.h"
#include "Widget/Curve/CreateHyperbolaWidget.h"
#include "Widget/Curve/CreateParabolaWidget.h"
#include <gp_Elips.hxx>
#include <Geom_Ellipse.hxx>
#include <gp_Parab.hxx>
#include <Geom_Parabola.hxx>
#include <gp_Hypr.hxx>
#include <Geom_Hyperbola.hxx>
#include <vtkCamera.h>
#include "FeatureShape/ShapeOperation.h"
#include <QPointer>
#include <QVariant>
#include "FeatureShape/QShapeVersion.h"
#include "FeatureShape/HistoryManager.h"
#include "FeatureShape/FeatureShape.h"
#include "Expression/QRSExpressionWidget.h"
#include <QFileDialog.h>

#include <QTimer>
#include "MainWindowManager.h"
#include "Sketch/QRWSketchCreateWidget.h"
#include "Sketch/QSketchManager.h"
#include <GC_MakeCircle.hxx>
#include "TempActorManager.h"
#include <BRepBuilderAPI_MakePolygon.hxx>
#include <QActionGroup>
#include "Serialize/RWShapeSerializeManager.h"
#include "Widget/Operation/QCreateFromObjectOperation.h"
#include "Widget/Operation/QDetachEdgeOperation.h"
#include "Widget/Operation/QDetachFaceOperation.h"
#include "Widget/Operation/QUncoverFaceOperation.h"
#include "Widget/Operation/QCoverFaceOperation.h"
#include "Widget/Operation/QMoveFaceOperation.h"
#include "Widget/Operation/QMoveEdgeOperation.h"
#include "Widget/Operation/QSectionOpertaion.h"


#define LINEWIDTH 3

static float GetPntFeatureValue(const gp_Pnt& point)
{
    return point.X() * 1.3 + point.Y() * 2.6 + point.Z() * 3.95;
}
static float GetDirFeatureValue(const gp_Dir& dir)
{
    return dir.X() + dir.Y() * 2.45 + dir.Z() * 3.98;
}
static float GetAx2FeatureValue(const gp_Ax2& axis)
{
    return GetPntFeatureValue(axis.Location()) * 1.3 + GetDirFeatureValue(axis.XDirection()) * 2.78 + GetDirFeatureValue(axis.YDirection()) * 3.15;
}

MainWindow::MainWindow(QWidget *parent)
	: SARibbonMainWindow(parent)
	, ui(new Ui::MainWindowClass())
{
	ui->setupUi(this);

	// list view
	// 注册 QPointer<ShapeOperation> 类型
	qRegisterMetaType<QPointer<QShapeVersion>>("QPointer<QShapeVersion>");

	m_listView = ui->listView;
	m_listModel = new QStandardItemModel(m_listView);
	m_listView->setModel(m_listModel);
	// 禁用直接编辑
	m_listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
	m_historyManager = new HistoryManager(m_listModel, m_listView, this);
	m_expressionManager = m_historyManager->GetExpressionManager();

	//初始化VTK的渲染器
	m_renderWindow = vtkGenericOpenGLRenderWindow::New();
	//将渲染器加入到VTK窗口中。
	ui->qvtkWidget->setRenderWindow(m_renderWindow);

	m_renderer = vtkSmartPointer<vtkRenderer>::New();
	m_renderer->SetBackground(Colors::Background);

	m_interactor = WindowInteractor::New();
	m_interactorStyle = WindowInteractorStyle::New(); //创建vtk相机交互器样式
	m_interactorStyle->m_mainWindow = this;

	m_interactor->SetRenderWindow(m_renderWindow); //设置渲染窗口
	m_propPicker = vtkSmartPointer<vtkPropPicker>::New();
	m_interactor->SetPicker(m_propPicker); //设置vtk Picker
	m_interactor->SetInteractorStyle(m_interactorStyle); //设置交互器样式

	m_shapePicker = vtkSmartPointer<IVtkTools_ShapePicker>::New();
	m_shapePicker->SetRenderer(m_renderer);
	m_shapePicker->SetTolerance(0.5f);
	m_interactorStyle->setVTKRenderWindow(m_renderWindow);
	m_interactorStyle->setOcctPicker(m_shapePicker); //设置occ Picker

	//初始化交互器
	m_interactor->Initialize();
	m_interactor->StartPickCallback();
	
	m_renderWindow->AddRenderer(m_renderer);

	// 平行投影
	m_camera = m_renderer->GetActiveCamera();
	m_camera->ParallelProjectionOn();
	m_renderer->ResetCamera();

	this->resize(1600, 900);
	this->setWindowTitle("OpenCascade CAD 3D modeling");

	/*****************************************SARibbon UI  Start************************************************/
	setWindowIcon(QIcon(".//Resource//logo.png"));

	m_mainBar = ribbonBar();
	createFileButton();
	createQuickAccessBar();
	createModelCategory();
	createViewCategoty();
	createSketchCategory();

	// 在构造函数设置主题会不完全生效
	QTimer::singleShot(0, this, [this]() 
		{
			this->setRibbonTheme(SARibbonTheme::RibbonThemeWindows7);
		});
	/*****************************************SARibbon UI  End************************************************/

	// 设置默认视图-前视图
	m_interactorStyle->SetStandardView(m_renderer, EViewStytle::frontView);

	deleteSelectActorsAction = createAction(tr("删除特征"), ".//Resource//delete.png");
	connect(deleteSelectActorsAction, &QAction::triggered, this, &MainWindow::onDeleteActionTriggered);
	editActorAction = createAction(tr("编辑特征"), ".//Resource//edit.png");
	connect(editActorAction, &QAction::triggered, this, &MainWindow::onEditActionTriggered);

	// 坐标系--注意等到相关初始化完毕之后添加
	m_coord = vtkSmartPointer<vtkTipsCoordinate>::New();
	m_coord->SetRenderer(m_renderer, m_interactor);
	m_coord->AddToRenderer();
	m_coord->HandlePickable(this);

	// 草图
	m_sketchManager = new QSketchManager(this);
	m_tempActorManager = std::make_shared<TempActorManager>(this);

}

MainWindow::~MainWindow()
{
	m_cacheActors.clear();
	delete cubeAction;
	delete ui;
}

void MainWindow::createQuickAccessBar()
{
	m_quickAccessBar = ribbonBar()->quickAccessBar();

	m_quickAccessBar->addAction(saveAction);
	m_quickAccessBar->addSeparator();

	// 撤销
	undoAction = createAction(tr("撤销"), ".//Resource//undo.png");
	undoAction->setShortcuts(QKeySequence::Undo);
	connect(undoAction, &QAction::triggered, this, &MainWindow::onUndo);
	m_quickAccessBar->addAction(undoAction);
	// 重做
	redoAction = createAction(tr("重做"), ".//Resource//redo.png");
	redoAction->setShortcuts(QKeySequence::Redo);
	connect(redoAction, &QAction::triggered, this, &MainWindow::onRedo);
	m_quickAccessBar->addAction(redoAction);

	m_quickAccessBar->addSeparator();
}

void MainWindow::createModelCategory()
{
	SARibbonCategory* modelCategory = new SARibbonCategory();
	modelCategory->setCategoryName(tr("建模"));
	modelCategory->setObjectName(("modelCategory"));
	m_mainBar->addCategoryPage(modelCategory);

	SARibbonPannel* basicFeatureModelPannel = modelCategory->addPannel(tr("基本特征建模"));
	SARibbonPannel* curveFeaturePannel = modelCategory->addPannel(tr("曲线特征"));
	SARibbonPannel* detailPannel = modelCategory->addPannel(tr("细节特征"));
	SARibbonPannel* designFeaturePannel = modelCategory->addPannel(tr("设计特征"));
	SARibbonPannel* geometryPannel = modelCategory->addPannel(tr("几何运算"));
	SARibbonPannel* toolPannel = modelCategory->addPannel(tr("工具"));

	/********************************基本特征建模*******************************/
	// cube
	cubeAction = basicFeatureModelPannel->addAction(QString("长方体"), QIcon(".//Resource//mk_box.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(cubeAction, &QAction::triggered, this, &MainWindow::onCubeActionTriggered);
	// sphere
	sphereAction = basicFeatureModelPannel->addAction(QString("球体"), QIcon(".//Resource//mk_sphere.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(sphereAction, &QAction::triggered, this, &MainWindow::onSphereActionTriggered);
	// 圆柱体
	cylinderAction = basicFeatureModelPannel->addAction(QString("圆柱体"), QIcon(".//Resource//mk_cylinder.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(cylinderAction, &QAction::triggered, this, &MainWindow::onCylinderActionTriggered);
	// 圆环
	torusAction = basicFeatureModelPannel->addAction(QString("圆环"), QIcon(".//Resource//mk_torus.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(torusAction, &QAction::triggered, this, &MainWindow::onTorusActionTriggered);
	// 圆锥
	coneAction = basicFeatureModelPannel->addAction(QString("圆锥"), QIcon(".//Resource//mk_cone.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(coneAction, &QAction::triggered, this, &MainWindow::onConeActionTriggered);

	/********************************曲线特侦*******************************/
	// 直线
	lineAction = curveFeaturePannel->addAction(QString("直线"), QIcon(".//Resource//mk_line.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(lineAction, &QAction::triggered, this, &MainWindow::onLineActionTriggered);
	// 圆
	circleAction = curveFeaturePannel->addAction(QString("圆弧"), QIcon(".//Resource//mk_ArcCircle.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(circleAction, &QAction::triggered, this, &MainWindow::onCircleActionTriggered);
	// 椭圆
	ellipseAction = curveFeaturePannel->addAction(QString("椭圆"), QIcon(".//Resource//mk_ellipse.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(ellipseAction, &QAction::triggered, this, &MainWindow::onEllipseActionTriggered);
	// 抛物线
	parabolaAction = curveFeaturePannel->addAction(QString("抛物线"), QIcon(".//Resource//mk_parabola.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(parabolaAction, &QAction::triggered, this, &MainWindow::onParabolaActionTriggered);
	// 双曲线
	hyperbolaAction = curveFeaturePannel->addAction(QString("双曲线"), QIcon(".//Resource//mk_hyperbola.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(hyperbolaAction, &QAction::triggered, this, &MainWindow::onHyperbolaActionTriggered);

	/********************************细节特征*******************************/
	// 倒圆角
	roundOffAction = detailPannel->addAction(QString("倒圆角"), QIcon(".//Resource//roundOff.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(roundOffAction, &QAction::triggered, this, &MainWindow::onRoundOffActionTriggered);

	/********************************设计特征*******************************/
	// 拉伸
	stretchAction = designFeaturePannel->addAction(QString("拉伸运算"), QIcon(".//Resource//stretch.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(stretchAction, &QAction::triggered, this, &MainWindow::onStretchActionTriggered);
	// 旋转
	rotateAction = designFeaturePannel->addAction(QString("旋转运算"), QIcon(".//Resource//revolve.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(rotateAction, &QAction::triggered, this, &MainWindow::onRevolveActionTriggered);
	// 抽壳
	hollowAction = designFeaturePannel->addAction(QString("抽壳"), QIcon(".//Resource//hollow.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(hollowAction, &QAction::triggered, this, &MainWindow::onHollowActionTriggered);
	// 填充
    fillAction = designFeaturePannel->addAction(QString("填充"), QIcon(".//Resource//fillFace.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    connect(fillAction, &QAction::triggered, this, &MainWindow::onFillActionTriggered);


	/********************************几何运算*******************************/
	// 布尔运算
	booleanAction = geometryPannel->addAction(QString("布尔运算"), QIcon(".//Resource//boolean.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(booleanAction, &QAction::triggered, this, &MainWindow::onBooleanActionTriggered);

	/********************************工具*******************************/
	// 表达式
	expressionAction = toolPannel->addAction(QString("表达式"), QIcon(".//Resource//expression.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(expressionAction, &QAction::triggered, this, &MainWindow::onEexpressionActionTriggered);
	// 变换
	translateAction = toolPannel->addAction(QString("变换"), QIcon(".//Resource//transform.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(translateAction, &QAction::triggered, this, &MainWindow::onTransformActionTriggered);
	// 从Object创建面或边
    QAction* createFromObjectAction = toolPannel->addAction(QString("Create From Object"), QIcon(".//Resource//createFromObject.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	auto createFromLambda = [this]() {
		CreateFromObjectWidget();
	};
    connect(createFromObjectAction, &QAction::triggered, this, createFromLambda);
	// 从wire拆分edge
	QAction* DetachEdgeAction = toolPannel->addAction(QString("Detach Edge"), QIcon(".//Resource//DetachEdge.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    auto DetachEdgeLambda = [this]() {
		DetachEdgeWidget();
	};
    connect(DetachEdgeAction, &QAction::triggered, this, DetachEdgeLambda);
	// 从sheets或solid拆分face
    QAction* DetachFaceAction = toolPannel->addAction(QString("Detach Face"), QIcon(".//Resource//DetachFace.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    auto DetachFaceLambda = [this]() {
		DetachFaceWidget();
	};
    connect(DetachFaceAction, &QAction::triggered, this, DetachFaceLambda);
	// uncover face
	QAction* uncoverFaceAction = toolPannel->addAction(QString("Uncover Face"), QIcon(".//Resource//uncoverFace.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	auto UncoverFaceLambda = [this]() {
		UncoverFaceWidget();
	};
	connect(uncoverFaceAction, &QAction::triggered, this, UncoverFaceLambda);
	// cover face
	QAction* coverFaceAction = toolPannel->addAction(QString("Cover Face"), QIcon(".//Resource//CoverFace.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	auto coverFaceLambda = [this]() {
		CoverFaceWidget();
	};
	connect(coverFaceAction, &QAction::triggered, this, coverFaceLambda);
	// Move face
	QAction* moveFaceAction = toolPannel->addAction(QString("Move Face"), QIcon(".//Resource//MoveFace.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	auto moveFaceLambda = [this]() {
		MoveFaceWidget();
	};
	connect(moveFaceAction, &QAction::triggered, this, moveFaceLambda);
	// Move edge
	QAction* moveEdgeAction = toolPannel->addAction(QString("Move Edge"), QIcon(".//Resource//MoveEdge.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	auto moveEdgeLambda = [this]() {
		MoveEdgeWidget();
	};
	connect(moveEdgeAction, &QAction::triggered, this, moveEdgeLambda);
	// Section
    QAction* sectionAction = toolPannel->addAction(QString("Section"), QIcon(".//Resource//Section.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    auto sectionLambda = [this]() {
		SectionWidget();
	};
    connect(sectionAction, &QAction::triggered, this, sectionLambda);
}

void MainWindow::createFileButton()
{
	QAbstractButton* fileButton = m_mainBar->applicationButton();
	fileButton->setText(tr("文件"));
	// 保存
	saveAction = new QAction(QIcon(".//Resource//save.png"), QString("保存"));
	connect(saveAction, &QAction::triggered, this, &MainWindow::onSave);
	saveAction->setShortcuts(QKeySequence::Save);
	fileButton->addAction(saveAction);
	// 读取
	loadAction = new QAction(QIcon(".//Resource//load.png"), QString("读取"));
	connect(loadAction, &QAction::triggered, this, &MainWindow::onLoad);
	fileButton->addAction(loadAction);
	// 新建
	newAction = new QAction(QIcon(".//Resource//new.png"), QString("新建"));
	connect(newAction, &QAction::triggered, this, &MainWindow::onNew);
	fileButton->addAction(newAction);
}

void MainWindow::createViewCategoty()
{
	SARibbonCategory* viewCategory = new SARibbonCategory();
	viewCategory->setCategoryName(tr("视图"));
	viewCategory->setObjectName(("viewCategory"));
	m_mainBar->addCategoryPage(viewCategory);

	SARibbonPannel* viewSelectionPannel = viewCategory->addPannel(tr("定向视图"));
	SARibbonPannel* viewOperationPannel = viewCategory->addPannel(tr("视图操作"));
	SARibbonPannel* vertexSelectFilterPannel = viewCategory->addPannel(tr("点选择器过滤"));
	vertexSelectFilterPannel->setSpacing(5);

	/********************************定向视图*******************************/
	frontView = viewSelectionPannel->addAction(QString("前视图"), QIcon(".//Resource//frontView.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    connect(frontView, &QAction::triggered, this, &MainWindow::onFrontViewActionTriggered);
	backView = viewSelectionPannel->addAction(QString("后视图"), QIcon(".//Resource//backView.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    connect(backView, &QAction::triggered, this, &MainWindow::onBackViewActionTriggered);
    topView = viewSelectionPannel->addAction(QString("仰视图"), QIcon(".//Resource//topView.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    connect(topView, &QAction::triggered, this, &MainWindow::onTopViewActionTriggered);
    bottomView = viewSelectionPannel->addAction(QString("俯视图"), QIcon(".//Resource//bottomView.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    connect(bottomView, &QAction::triggered, this, &MainWindow::onBottomViewActionTriggered);
    leftView = viewSelectionPannel->addAction(QString("左视图"), QIcon(".//Resource//leftView.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    connect(leftView, &QAction::triggered, this, &MainWindow::onLeftViewActionTriggered);
    rightView = viewSelectionPannel->addAction(QString("右视图"), QIcon(".//Resource//rightView.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    connect(rightView, &QAction::triggered, this, &MainWindow::onRightViewActionTriggered);
	positiveTriaxialView = viewSelectionPannel->addAction(QString("正三轴视图"), QIcon(".//Resource//positiveTriaxialView.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    connect(positiveTriaxialView, &QAction::triggered, this, &MainWindow::onPositiveTriaxialViewActionTriggered);

	/********************************视图操作*******************************/
	fitView = viewOperationPannel->addAction(QString("适应视图"), QIcon(".//Resource//fitView.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    connect(fitView, &QAction::triggered, this, &MainWindow::onFitViewActionTriggered);
	hideAllActorsAction = viewOperationPannel->addAction(QString("隐藏所有"), QIcon(".//Resource//hide.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(hideAllActorsAction, &QAction::triggered, this, 
		[this]() 
		{
			SetCachedActorVisibility(false);
		});
	showAllActorsAction = viewOperationPannel->addAction(QString("显示所有"), QIcon(".//Resource//show.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(showAllActorsAction, &QAction::triggered, this,
		[this]()
		{
			SetCachedActorVisibility(true);
		});
	hideSelectAcotrAction = createAction(tr("隐藏"), ".//Resource//hideSelect.png");
	connect(hideSelectAcotrAction, &QAction::triggered, this, &MainWindow::HideSelectedActors);

	/********************************点选择器过滤*******************************/
	selectEdgeEndVertex = vertexSelectFilterPannel->addAction(QString("边端点"), QIcon(".//Resource//EdgeEndVertex.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	selectEdgeEndVertex->setCheckable(true);
	selectEdgeEndVertex->setChecked(true);
	selectEdgeEndVertex->setToolTip(QString("允许选择曲线的端点"));
    connect(selectEdgeEndVertex, &QAction::triggered, this, &MainWindow::onSelectEdgeEndVertexActionTriggered);
    selectEdgeDividedVertex = vertexSelectFilterPannel->addAction(QString("边中点"), QIcon(".//Resource//EdgeMidVertex.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    selectEdgeDividedVertex->setCheckable(true);
    selectEdgeDividedVertex->setChecked(true);
    selectEdgeDividedVertex->setToolTip(QString("允许选择曲线的中点"));
    connect(selectEdgeDividedVertex, &QAction::triggered, this, &MainWindow::onSelectEdgeDividedVertexActionTriggered);
	selectFaceMidVertex = vertexSelectFilterPannel->addAction(QString("面中点"), QIcon(".//Resource//FaceMidVertex.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    selectFaceMidVertex->setCheckable(true);
    selectFaceMidVertex->setChecked(true);
    selectFaceMidVertex->setToolTip(QString("允许选择面参数空间的中点"));
    connect(selectFaceMidVertex, &QAction::triggered, this, &MainWindow::onSelectFaceMidVertexActionTriggered);
    selectIntersectionVertex = vertexSelectFilterPannel->addAction(QString("交点"), QIcon(".//Resource//IntersectionVertex.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    selectIntersectionVertex->setCheckable(true);
    selectIntersectionVertex->setChecked(true);
    selectIntersectionVertex->setToolTip(QString("允许选择曲线之间的交点"));
    connect(selectIntersectionVertex, &QAction::triggered, this, &MainWindow::onSelectIntersectionVertexActionTriggered);
    selectCircleCenterVertex = vertexSelectFilterPannel->addAction(QString("圆心"), QIcon(".//Resource//CircleCenterVertex.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    selectCircleCenterVertex->setCheckable(true);
    selectCircleCenterVertex->setChecked(true);
    selectCircleCenterVertex->setToolTip(QString("允许选择圆弧或椭圆的中心点"));
    connect(selectCircleCenterVertex, &QAction::triggered, this, &MainWindow::onSelectCircleCenterVertexActionTriggered);

	m_interactorStyle->_selectedVertexTypes.insert(EVertexType::EdgeEndVertex);
    m_interactorStyle->_selectedVertexTypes.insert(EVertexType::EdgeDividedVertex);
    m_interactorStyle->_selectedVertexTypes.insert(EVertexType::FaceMidVertex);
    m_interactorStyle->_selectedVertexTypes.insert(EVertexType::IntersectionVertex);
    m_interactorStyle->_selectedVertexTypes.insert(EVertexType::CircleCenterVertex);
}

void MainWindow::createSketchCategory()
{
	SARibbonCategory* sketchCategory = new SARibbonCategory();
	sketchCategory->setCategoryName(tr("草图"));
	sketchCategory->setObjectName(("sketchCategory"));
	m_mainBar->addCategoryPage(sketchCategory);

	SARibbonPannel* statePannel = sketchCategory->addPannel(tr("草图"));
	SARibbonPannel* curvePannel = sketchCategory->addPannel(tr("曲线"));
	SARibbonPannel* vertexSelectFilterPannel = sketchCategory->addPannel(tr("点过滤"));
	SARibbonPannel* toolPannel = sketchCategory->addPannel(tr("工具"));

	// 创建 QActionGroup 并设置为互斥
	QActionGroup* group = new QActionGroup(this);

	// ---------------------状态栏---------------------
	sketchAction = statePannel->addAction(QString("创建草图"), QIcon(".//Resource//CreateSketch.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	connect(sketchAction, &QAction::triggered, this, &MainWindow::onSketchActionTriggered);
	finishSketchAction = statePannel->addAction(QString("完成草图"), QIcon(".//Resource//finishSketch.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	finishSketchAction->setEnabled(false);
	connect(finishSketchAction, &QAction::triggered, this,
		[this]()
		{
			m_sketchManager->FinishCreateSketch();
		});

	// ---------------------曲线栏---------------------
	QAction* sketchLine = curvePannel->addAction(QString("直线"), QIcon(".//Resource//mk_line.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	sketchLine->setCheckable(true);
	group->addAction(sketchLine);
	connect(sketchLine, &QAction::triggered, this,
		[this]()
		{
			m_sketchManager->CreateSketchCurve(ESketchCurveType::Line);
		});
	QAction* sketchCircle = curvePannel->addAction(QString("圆"), QIcon(".//Resource//mk_circle.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	sketchCircle->setCheckable(true);
    group->addAction(sketchCircle);
	connect(sketchCircle, &QAction::triggered, this,
		[this]()
		{
			m_sketchManager->CreateSketchCurve(ESketchCurveType::Circle);
		});
	QAction* sketchArcCircle = curvePannel->addAction(QString("圆弧"), QIcon(".//Resource//mk_arcCircle.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    sketchArcCircle->setCheckable(true);
    group->addAction(sketchArcCircle);
	connect(sketchArcCircle, &QAction::triggered, this,
		[this]()
		{
			m_sketchManager->CreateSketchCurve(ESketchCurveType::ArcCircle);
		});
	QAction* sketcRectangle = curvePannel->addAction(QString("矩形"), QIcon(".//Resource//mk_rectangle.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    sketcRectangle->setCheckable(true);
    group->addAction(sketcRectangle);
	connect(sketcRectangle, &QAction::triggered, this,
		[this]()
		{
			m_sketchManager->CreateSketchCurve(ESketchCurveType::Rectangle);
		});

	// ---------------------点过滤栏---------------------
	vertexSelectFilterPannel->setSpacing(5);
	QAction* randomVertex = vertexSelectFilterPannel->addAction(QString("任意点"), QIcon(".//Resource//randomPoint.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	randomVertex->setCheckable(true);
	randomVertex->setChecked(true);
	randomVertex->setToolTip(QString("允许选择屏幕任意点"));
	connect(randomVertex, &QAction::triggered, this,
		[this, randomVertex]()
		{
			m_sketchManager->filterSelectVertexType(EVertexType::RandomVertex, randomVertex);
		});
	QAction* endVertex = vertexSelectFilterPannel->addAction(QString("边端点"), QIcon(".//Resource//EdgeEndVertex.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	endVertex->setCheckable(true);
	endVertex->setChecked(true);
	endVertex->setToolTip(QString("允许选择曲线的端点"));
	connect(endVertex, &QAction::triggered, this,
		[this, endVertex]()
		{
			m_sketchManager->filterSelectVertexType(EVertexType::EdgeEndVertex, endVertex);
		});
	QAction* midVertex = vertexSelectFilterPannel->addAction(QString("边中点"), QIcon(".//Resource//EdgeMidVertex.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	midVertex->setCheckable(true);
	midVertex->setChecked(true);
	midVertex->setToolTip(QString("允许选择曲线的中点"));
	connect(midVertex, &QAction::triggered, this,
		[this, midVertex]()
		{
			m_sketchManager->filterSelectVertexType(EVertexType::EdgeDividedVertex, midVertex);
		});
	QAction* intersectionVertex = vertexSelectFilterPannel->addAction(QString("交点"), QIcon(".//Resource//IntersectionVertex.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	intersectionVertex->setCheckable(true);
	intersectionVertex->setChecked(true);
	intersectionVertex->setToolTip(QString("允许选择曲线之间的交点"));
	connect(intersectionVertex, &QAction::triggered, this,
		[this, intersectionVertex]()
		{
			m_sketchManager->filterSelectVertexType(EVertexType::IntersectionVertex, intersectionVertex);
		});
	QAction* centerVertex = vertexSelectFilterPannel->addAction(QString("圆心"), QIcon(".//Resource//CircleCenterVertex.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	centerVertex->setCheckable(true);
	centerVertex->setChecked(true);
	centerVertex->setToolTip(QString("允许选择圆弧或椭圆的中心点"));
	connect(centerVertex, &QAction::triggered, this,
		[this, centerVertex]()
		{
			m_sketchManager->filterSelectVertexType(EVertexType::CircleCenterVertex, centerVertex);
		});

	// ---------------------操作栏---------------------
	QAction* trimCurve = toolPannel->addAction(QString("修剪"), QIcon(".//Resource//trim.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
	trimCurve->setCheckable(true);
	group->addAction(trimCurve);
	connect(trimCurve, &QAction::triggered, this,
		[this]()
		{
			m_sketchManager->TrimCurve();
		});
	QAction* extendCurve = toolPannel->addAction(QString("延伸"), QIcon(".//Resource//extend.png"), QToolButton::InstantPopup, SARibbonPannelItem::Large);
    extendCurve->setCheckable(true);
	group->addAction(extendCurve);
	connect(extendCurve, &QAction::triggered, this,
		[this]()
		{
			m_sketchManager->ExtendCurve();
		});
}

void MainWindow::SketchActionResponse(bool bStart)
{
	sketchAction->setEnabled(!bStart);
	finishSketchAction->setEnabled(bStart);
	bSketchActionInProgress = bStart;
}

void MainWindow::onCubeActionTriggered()
{
	CubeWidget();
}

void MainWindow::onSphereActionTriggered()
{
	SphereWidget();
}

void MainWindow::onCylinderActionTriggered()
{
	CylinderWidget();
}

void MainWindow::onTorusActionTriggered()
{
	TorusWidget();
}

void MainWindow::onConeActionTriggered()
{
	ConeWidget();
}

void MainWindow::onLineActionTriggered()
{
	LineWidget();
}

void MainWindow::onCircleActionTriggered()
{
	CircleWidget();
}

void MainWindow::onEllipseActionTriggered()
{
	EllipseWidget();
}

void MainWindow::onParabolaActionTriggered()
{
	ParabolaWidget();
}

void MainWindow::onHyperbolaActionTriggered()
{
	HyperbolaWidget();
}

void MainWindow::onBooleanActionTriggered()
{
	BooleanWidget();
}

void MainWindow::onTransformActionTriggered()
{
	TransformWidget();
}

void MainWindow::onStretchActionTriggered()
{
	StretchWidget();
}

void MainWindow::onRevolveActionTriggered()
{
	RevolveWidget();
}

void MainWindow::onRoundOffActionTriggered()
{
	RoundOffWidget();
}

void MainWindow::onHollowActionTriggered()
{
	HollowWidget();
}

void MainWindow::onRedo()
{
	if (bSketchActionInProgress)
	{
        m_sketchManager->redo();
	}
	else
	{
		m_historyManager->redo();
	}
}

void MainWindow::onUndo()
{
	if (bSketchActionInProgress)
	{
		m_sketchManager->undo();
	}
	else
	{
		m_historyManager->undo();
	}
}

void MainWindow::onSave()
{
	m_historyManager->saveOperations();
}

void MainWindow::onLoad()
{
	QString fileName = QFileDialog::getOpenFileName(
		this,                    // 父窗口（这里为nullptr表示没有父窗口）
		tr("Open File"),            // 对话框标题
		"./save",                         // 默认目录（空字符串表示用户主目录）
		tr("Binary Files (*.bin)") // 文件过滤器
	);

	if (!fileName.isEmpty()) 
	{
		qDebug() << "Selected binary file:" << fileName;
		if (m_historyManager->IsModify())
		{
			std::shared_ptr<MainWindow> newWindow = MainWindowManager::GetInstance()->NewMainWindow();
			newWindow->m_historyManager->loadOperations(fileName.toStdString());
		}
		else
		{
			m_historyManager->loadOperations(fileName.toStdString());
		}
	}
	else 
	{
		qDebug() << "No file selected.";
	}
}

void MainWindow::onNew()
{
	MainWindowManager::GetInstance()->NewMainWindow();
}

void MainWindow::onFrontViewActionTriggered()
{
	m_interactorStyle->SetStandardView(m_renderer, EViewStytle::frontView);
}

void MainWindow::onBackViewActionTriggered()
{
    m_interactorStyle->SetStandardView(m_renderer, EViewStytle::backView);
}

void MainWindow::onTopViewActionTriggered()
{
    m_interactorStyle->SetStandardView(m_renderer, EViewStytle::topView);
}

void MainWindow::onLeftViewActionTriggered()
{
    m_interactorStyle->SetStandardView(m_renderer, EViewStytle::leftView);
}

void MainWindow::onRightViewActionTriggered()
{
    m_interactorStyle->SetStandardView(m_renderer, EViewStytle::rightView);
}

void MainWindow::onBottomViewActionTriggered()
{
    m_interactorStyle->SetStandardView(m_renderer, EViewStytle::bottomView);
}

void MainWindow::onPositiveTriaxialViewActionTriggered()
{
    m_interactorStyle->SetStandardView(m_renderer, EViewStytle::positiveTriaxialView);
}

void MainWindow::onFitViewActionTriggered()
{
	m_interactorStyle->SetFitView(m_renderer);
}

void MainWindow::onSelectEdgeEndVertexActionTriggered()
{
	if (m_interactorStyle->_selectedVertexTypes.count(EVertexType::EdgeEndVertex))
	{
        m_interactorStyle->_selectedVertexTypes.erase(EVertexType::EdgeEndVertex);
        selectEdgeEndVertex->setChecked(false);
	}
	else
	{
        m_interactorStyle->_selectedVertexTypes.insert(EVertexType::EdgeEndVertex);
        selectEdgeEndVertex->setChecked(true);
	}
}

void MainWindow::onSelectEdgeDividedVertexActionTriggered()
{
    if (m_interactorStyle->_selectedVertexTypes.count(EVertexType::EdgeDividedVertex))
	{
        m_interactorStyle->_selectedVertexTypes.erase(EVertexType::EdgeDividedVertex);
        selectEdgeDividedVertex->setChecked(false);
	}
	else
	{
        m_interactorStyle->_selectedVertexTypes.insert(EVertexType::EdgeDividedVertex);
        selectEdgeDividedVertex->setChecked(true);
	}
}

void MainWindow::onSelectFaceMidVertexActionTriggered()
{
    if (m_interactorStyle->_selectedVertexTypes.count(EVertexType::FaceMidVertex))
	{
        m_interactorStyle->_selectedVertexTypes.erase(EVertexType::FaceMidVertex);
        selectFaceMidVertex->setChecked(false);
	}
	else
	{
        m_interactorStyle->_selectedVertexTypes.insert(EVertexType::FaceMidVertex);
        selectFaceMidVertex->setChecked(true);
	}
}

void MainWindow::onSelectIntersectionVertexActionTriggered()
{
    if (m_interactorStyle->_selectedVertexTypes.count(EVertexType::IntersectionVertex))
	{
        m_interactorStyle->_selectedVertexTypes.erase(EVertexType::IntersectionVertex);
        selectIntersectionVertex->setChecked(false);
	}
	else
	{
        m_interactorStyle->_selectedVertexTypes.insert(EVertexType::IntersectionVertex);
        selectIntersectionVertex->setChecked(true);
	}
}

void MainWindow::onSelectCircleCenterVertexActionTriggered()
{
    if (m_interactorStyle->_selectedVertexTypes.count(EVertexType::CircleCenterVertex))
	{
        m_interactorStyle->_selectedVertexTypes.erase(EVertexType::CircleCenterVertex);
        selectCircleCenterVertex->setChecked(false);
	}
	else
	{
        m_interactorStyle->_selectedVertexTypes.insert(EVertexType::CircleCenterVertex);
        selectCircleCenterVertex->setChecked(true);
	}
}

void MainWindow::onSketchActionTriggered()
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	QRWSketchCreateWidget* sketchCreateWidget = new QRWSketchCreateWidget(this, nullptr, this);
	sketchCreateWidget->setWindowTitle("创建草图");
	sketchCreateWidget->setFixedSize(QSize(340, 405));
	sketchCreateWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	sketchCreateWidget->show();
}

void MainWindow::onFillActionTriggered()
{
	FillWidget();
}

void MainWindow::onDeleteActionTriggered()
{
	// 先获得index
	std::vector<int> deleteActorsIndex;
	for (Handle(QIVtkSelectionPipeline) actor : m_interactorStyle->selectActors)
	{
		deleteActorsIndex.push_back(GetIndexFromActor(GetCachedActors(), actor));
	}

	while (m_interactorStyle->selectActors.size())
	{
		RemoveActorFromRenderer(m_interactorStyle->selectActors.back());
	}

	DeleteShapeOperation* op = new DeleteShapeOperation("删除所选特征", deleteActorsIndex);
	GetHistoryManager()->applyOperation(op);
}

void MainWindow::onEditActionTriggered()
{
	Handle(QIVtkSelectionPipeline) editActor = m_interactorStyle->selectActors.back();
	// 清空
	m_interactorStyle->ClearSelectedActors();

	m_historyManager->EditActor(editActor);
}

void MainWindow::HideSelectedActors()
{
	for (Handle(QIVtkSelectionPipeline) actor : m_interactorStyle->selectActors)
	{
		actor->SetPipelineVisibility(false);
		m_hidedActors.push_back(actor);
	}
	m_interactorStyle->ClearSelectedActors();

	FlushRender();
}

void MainWindow::SetCachedActorVisibility(bool visible)
{
	m_hidedActors.clear();
	m_interactorStyle->ClearSelectedActors();
	for (Handle(QIVtkSelectionPipeline) actor : m_cacheActors)
	{
		actor->SetPipelineVisibility(visible);
	}
	if (!visible)
	{
		m_hidedActors.insert(m_hidedActors.begin(), m_cacheActors.begin(), m_cacheActors.end());
	}

	FlushRender();
}

void MainWindow::onEexpressionActionTriggered()
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	QRSExpressionWidget* expressionWidget = new QRSExpressionWidget(this);
	expressionWidget->setWindowTitle("表达式");
	//hollowOperationWidget->setFixedSize(QSize(380, 280));
	//booleanOperationWidget->setWindowModality(Qt::ApplicationModal);
	expressionWidget->setWindowFlags(expressionWidget->windowFlags() | Qt::WindowStaysOnTopHint);
	expressionWidget->show();
}

Handle(QIVtkSelectionPipeline) MainWindow::createCube(float length, float width, float height)
{
	BRepPrimAPI_MakeBox box(width, length, height);
	Handle(QIVtkSelectionPipeline) actor = createBasicUnitActor(box.Shape());
	actor->featureValue = length + width + height;
	return actor;
}

Handle(QIVtkSelectionPipeline) MainWindow::createSphere(float radius)
{
	BRepPrimAPI_MakeSphere sphere(radius);
	Handle(QIVtkSelectionPipeline) actor = createBasicUnitActor(sphere.Shape());
	actor->featureValue = radius;
	return actor;
}

Handle(QIVtkSelectionPipeline) MainWindow::createCylinder(float radius, float height)
{
	BRepPrimAPI_MakeCylinder cylinder(radius, height);
	Handle(QIVtkSelectionPipeline) actor = createBasicUnitActor(cylinder.Shape());
	actor->featureValue = radius + height;
	return actor;
}

Handle(QIVtkSelectionPipeline) MainWindow::createTorus(float radiusOuter, float radiusInner)
{
	BRepPrimAPI_MakeTorus torus(radiusOuter, radiusInner);
	Handle(QIVtkSelectionPipeline) actor = createBasicUnitActor(torus.Shape());
	actor->featureValue = radiusOuter + radiusInner;
	return actor;
}

Handle(QIVtkSelectionPipeline) MainWindow::createCone(float radius1, float radius2, float height)
{
	BRepPrimAPI_MakeCone cone(radius1, radius2, height);
	Handle(QIVtkSelectionPipeline) actor = createBasicUnitActor(cone.Shape());
	actor->featureValue = radius1 + radius2 + height;
	return actor;
}

Handle(QIVtkSelectionPipeline) MainWindow::createLine(const gp_Pnt& p1, const gp_Pnt& p2)
{
	BRepBuilderAPI_MakeEdge edge(p1, p2);
	Handle(QIVtkSelectionPipeline) actor = createBasicUnitActor(edge.Shape());
	actor->featureValue = p1.Distance(p2) + GetPntFeatureValue(p1) + GetPntFeatureValue(p2);
	actor->Actor()->GetProperty()->SetLineWidth(LINEWIDTH);
	return actor;
}

Handle(QIVtkSelectionPipeline) MainWindow::createArcCircle(const gp_Pnt& start, const gp_Pnt& tangent, const gp_Pnt& end)
{
	// 创建圆弧
	Handle(Geom_TrimmedCurve) arc = GC_MakeArcOfCircle(start, tangent, end);
	// 将圆弧转换为拓扑边
	TopoDS_Edge arcEdge = BRepBuilderAPI_MakeEdge(arc);
	Handle(QIVtkSelectionPipeline) actor = createBasicUnitActor(arcEdge);
	actor->featureValue = start.Distance(tangent) + tangent.Distance(end) + GetPntFeatureValue(start)
							+ GetPntFeatureValue(tangent) + GetPntFeatureValue(end);
	actor->Actor()->GetProperty()->SetLineWidth(LINEWIDTH);
	return actor;
}

Handle(QIVtkSelectionPipeline) MainWindow::createCircle(const gp_Pnt& center, float radius, const gp_Dir& normal)
{
	Handle(Geom_Circle) circle = GC_MakeCircle(center, normal, radius);
	TopoDS_Edge circleEdge = BRepBuilderAPI_MakeEdge(circle);
	Handle(QIVtkSelectionPipeline) actor = createBasicUnitActor(circleEdge);
    actor->featureValue = radius + GetPntFeatureValue(center) + GetDirFeatureValue(normal);
    actor->Actor()->GetProperty()->SetLineWidth(LINEWIDTH);
    return actor;
}

Handle(QIVtkSelectionPipeline) MainWindow::createEllipse(const gp_Ax2& axis, float majorRadius, float minorRadius)
{
	gp_Elips ellipse(axis, majorRadius, minorRadius);
	Handle(Geom_Ellipse) geomEllipse = new Geom_Ellipse(ellipse);
	TopoDS_Edge ellipseEdge = BRepBuilderAPI_MakeEdge(geomEllipse);
	Handle(QIVtkSelectionPipeline) actor = createBasicUnitActor(ellipseEdge);
	actor->featureValue = majorRadius + minorRadius + GetAx2FeatureValue(axis);
	actor->Actor()->GetProperty()->SetLineWidth(LINEWIDTH);
	return actor;
}

Handle(QIVtkSelectionPipeline) MainWindow::createParabola(const gp_Ax2& axis, float focal, float startLen, float endLen)
{
	gp_Parab parabola(axis, focal);
	Handle(Geom_Parabola) geomParabola = new Geom_Parabola(parabola);
	TopoDS_Edge parabolaEdge = BRepBuilderAPI_MakeEdge(geomParabola, -startLen, endLen);
	Handle(QIVtkSelectionPipeline) actor = createBasicUnitActor(parabolaEdge);
    actor->featureValue = focal + GetAx2FeatureValue(axis) + startLen + endLen;
	actor->Actor()->GetProperty()->SetLineWidth(LINEWIDTH);
	return actor;
}

Handle(QIVtkSelectionPipeline) MainWindow::createHyperbola(const gp_Ax2& axis, float majorRadius, float minorRadius, float startLen, float endLen)
{
	gp_Hypr hyperbola(axis, majorRadius, minorRadius);
	Handle(Geom_Hyperbola) geomHyperbola = new Geom_Hyperbola(hyperbola);
	TopoDS_Edge hyperbolaEdge = BRepBuilderAPI_MakeEdge(geomHyperbola, -startLen, endLen);
	Handle(QIVtkSelectionPipeline) actor = createBasicUnitActor(hyperbolaEdge);
	actor->featureValue = majorRadius + minorRadius + GetAx2FeatureValue(axis) + startLen + endLen;
	actor->Actor()->GetProperty()->SetLineWidth(LINEWIDTH);
	return actor;
}

Handle(QIVtkSelectionPipeline) MainWindow::createRectangle(const gp_Pnt& p1, const gp_Pnt& p2, const gp_Pnt& p3, const gp_Pnt& p4)
{
	BRepBuilderAPI_MakePolygon polyBuilder(p1, p2, p3, p4, true);
	Handle(QIVtkSelectionPipeline) actor = createBasicUnitActor(polyBuilder.Wire());
	actor->featureValue = p1.Distance(p2) + p2.Distance(p3) + p3.Distance(p4) + 
		GetPntFeatureValue(p1) + GetPntFeatureValue(p2) + GetPntFeatureValue(p3) + GetPntFeatureValue(p4);
    actor->Actor()->GetProperty()->SetLineWidth(LINEWIDTH);
    return actor;
}

Handle(QIVtkSelectionPipeline) MainWindow::createActorFromFeatureShape(FeatureShape* shape, bool bAddToCache)
{
	if (!shape)
	{
		return nullptr;
	}

	Handle(QIVtkSelectionPipeline) actor;
	if (!shape->_shape.IsNull())
	{
		actor = createBasicUnitActor(shape->_shape, bAddToCache);
	}

	// 计算feature value
	if (shape->_featureType == EFeatureType::ArcCircle)
	{
		FeatureShapeArcCircle* arcCircle = static_cast<FeatureShapeArcCircle*>(shape);
		actor->featureValue = arcCircle->_start.Distance(arcCircle->_tangent) + arcCircle->_tangent.Distance(arcCircle->_end) + 
			GetPntFeatureValue(arcCircle->_start) + GetPntFeatureValue(arcCircle->_tangent) + GetPntFeatureValue(arcCircle->_end);
	}
	else if(shape->_featureType == EFeatureType::Cone)
	{
        FeatureShapeCone* cone = static_cast<FeatureShapeCone*>(shape);
        actor->featureValue = cone->_height + cone->_radius1 + cone->_radius2;
	}
	else if (shape->_featureType == EFeatureType::Cylinder)
	{
        FeatureShapeCylinder* cylinder = static_cast<FeatureShapeCylinder*>(shape);
        actor->featureValue = cylinder->_height + cylinder->_radius;
	}
    else if (shape->_featureType == EFeatureType::Ellipse)
	{
        FeatureShapeEllipse* ellipse = static_cast<FeatureShapeEllipse*>(shape);
        actor->featureValue = ellipse->_majorRadius + ellipse->_minorRadius + GetAx2FeatureValue(ellipse->_axis);
	}
    else if (shape->_featureType == EFeatureType::Hyperbola)
	{
        FeatureShapeHyperbola* hyperbola = static_cast<FeatureShapeHyperbola*>(shape);
        actor->featureValue = hyperbola->_majorRadius + hyperbola->_minorRadius + 
			GetAx2FeatureValue(hyperbola->_axis) + hyperbola->_startLen + hyperbola->_endLen;
	}
    else if (shape->_featureType == EFeatureType::Line)
	{
        FeatureShapeLine* line = static_cast<FeatureShapeLine*>(shape);
        actor->featureValue = line->_start.Distance(line->_end) + GetPntFeatureValue(line->_start) + GetPntFeatureValue(line->_end);
	}
    else if (shape->_featureType == EFeatureType::Parabola)
	{
        FeatureShapeParabola* parabola = static_cast<FeatureShapeParabola*>(shape);
        actor->featureValue = parabola->_focal + parabola->_startLen + parabola->_endLen + GetAx2FeatureValue(parabola->_axis);
	}
    else if (shape->_featureType == EFeatureType::Sphere)
	{
        FeatureShapeSphere* sphere = static_cast<FeatureShapeSphere*>(shape);
        actor->featureValue = sphere->_radius;
	}
    else if (shape->_featureType == EFeatureType::Torus)
	{
        FeatureShapeTorus* torus = static_cast<FeatureShapeTorus*>(shape);
        actor->featureValue = torus->_radiusOuter + torus->_radiusInner;
	}
    else if (shape->_featureType == EFeatureType::Cube)
	{
        FeatureShapeCube* cube = static_cast<FeatureShapeCube*>(shape);
        actor->featureValue = cube->_length + cube->_width + cube->_height;
	}
	else if (shape->_featureType == EFeatureType::Circle)
	{
        FeatureShapeCircle* circle = static_cast<FeatureShapeCircle*>(shape);
		actor->featureValue = circle->_radius + GetPntFeatureValue(circle->_center) + GetDirFeatureValue(circle->_normal);
	}
	else if (shape->_featureType == EFeatureType::Rectangle)
	{
        FeatureShapeRectangle* rectangle = static_cast<FeatureShapeRectangle*>(shape);
		actor->featureValue = rectangle->_p1.Distance(rectangle->_p2) + rectangle->_p2.Distance(rectangle->_p3) + 
			rectangle->_p3.Distance(rectangle->_p4) + GetPntFeatureValue(rectangle->_p1) + 
			GetPntFeatureValue(rectangle->_p2) + GetPntFeatureValue(rectangle->_p3) + GetPntFeatureValue(rectangle->_p4);
	}
	else if (shape->_featureType == EFeatureType::Mix)
	{
        FeatureShapeMix* mix = static_cast<FeatureShapeMix*>(shape);
		if (mix->_shapeFileName != "None")
		{
			TopoDS_Shape shape = RWShapeSerializeManager::LoadShape(mix->_shapeFileName);
			if (!shape.IsNull())
			{
				actor = createBasicUnitActor(shape, bAddToCache);
			}
		}
	}

	if (actor)
	{
		actor->m_position = shape->_position;
	}
	return actor;
}

Handle(QIVtkSelectionPipeline) MainWindow::UpdateCubeActor(Handle(QIVtkSelectionPipeline) actor, float length, float width, float height)
{
	if (IsNearlyEqual(actor->featureValue, length + width + height))
	{
		return actor;
	}

	RemoveActorFromRenderer(actor);
	m_interactorStyle->removePipeline(actor->GetShapeID());

	return createCube(length, width, height);
}

Handle(QIVtkSelectionPipeline) MainWindow::UpdateSphereActor(Handle(QIVtkSelectionPipeline) actor, float radius)
{
	if (IsNearlyEqual(actor->featureValue, radius))
	{
		return actor;
	}

	RemoveActorFromRenderer(actor);
	m_interactorStyle->removePipeline(actor->GetShapeID());

	return createSphere(radius);
}

Handle(QIVtkSelectionPipeline) MainWindow::UpdateCylinderActor(Handle(QIVtkSelectionPipeline) actor, float radius, float height)
{
	if (IsNearlyEqual(actor->featureValue, radius + height))
	{
		return actor;
	}

	RemoveActorFromRenderer(actor);
	m_interactorStyle->removePipeline(actor->GetShapeID());

	return createCylinder(radius, height);
}

Handle(QIVtkSelectionPipeline) MainWindow::UpdateTorusActor(Handle(QIVtkSelectionPipeline) actor, float radiusOuter, float radiusInner)
{
	if (IsNearlyEqual(actor->featureValue, radiusOuter + radiusInner))
	{
		return actor;
	}

	RemoveActorFromRenderer(actor);
	m_interactorStyle->removePipeline(actor->GetShapeID());

	return createTorus(radiusOuter, radiusInner);
}

Handle(QIVtkSelectionPipeline) MainWindow::UpdateConeActor(Handle(QIVtkSelectionPipeline) actor, float radius1, float radius2, float height)
{
	if (IsNearlyEqual(actor->featureValue, radius1 + radius2 + height))
	{
		return actor;
	}

	RemoveActorFromRenderer(actor);
	m_interactorStyle->removePipeline(actor->GetShapeID());

	return createCone(radius1, radius2, height);
}

Handle(QIVtkSelectionPipeline) MainWindow::UpdateLineActor(Handle(QIVtkSelectionPipeline) actor, const gp_Pnt& p1, const gp_Pnt& p2)
{
	if (IsNearlyEqual(actor->featureValue, p1.Distance(p2) + GetPntFeatureValue(p1) + GetPntFeatureValue(p2)))
	{
		return actor;
	}

	RemoveActorFromRenderer(actor);
	m_interactorStyle->removePipeline(actor->GetShapeID());

	return createLine(p1, p2);
}

Handle(QIVtkSelectionPipeline) MainWindow::UpdateCircleActor(Handle(QIVtkSelectionPipeline) actor, const gp_Pnt& start, const gp_Pnt& tangent, const gp_Pnt& end)
{
	if (IsNearlyEqual(actor->featureValue, start.Distance(tangent) + tangent.Distance(end) + 
		GetPntFeatureValue(start) + GetPntFeatureValue(tangent) + GetPntFeatureValue(end)))
	{
        return actor;
	}

	RemoveActorFromRenderer(actor);
	m_interactorStyle->removePipeline(actor->GetShapeID());

	return createArcCircle(start, tangent, end);
}

Handle(QIVtkSelectionPipeline) MainWindow::UpdateEllipseActor(Handle(QIVtkSelectionPipeline) actor, const gp_Ax2& axis, float majorRadius, float minorRadius)
{
	if (IsNearlyEqual(actor->featureValue, majorRadius + minorRadius + GetAx2FeatureValue(axis)))
	{
        return actor;
	}

	RemoveActorFromRenderer(actor);
    m_interactorStyle->removePipeline(actor->GetShapeID());

    return createEllipse(axis, majorRadius, minorRadius);
}

Handle(QIVtkSelectionPipeline) MainWindow::UpdateParabolaActor(Handle(QIVtkSelectionPipeline) actor, const gp_Ax2& axis, float focal, float startLen, float endLen)
{
	if (IsNearlyEqual(actor->featureValue, focal + GetAx2FeatureValue(axis) + startLen + endLen))
	{
		return actor;
	}

    RemoveActorFromRenderer(actor);
    m_interactorStyle->removePipeline(actor->GetShapeID());

    return createParabola(axis, focal, startLen, endLen);
}

Handle(QIVtkSelectionPipeline) MainWindow::UpdateHyperbolaActor(Handle(QIVtkSelectionPipeline) actor, const gp_Ax2& axis, float majorRadius, float minorRadius, float startLen, float endLen)
{
	if (IsNearlyEqual(actor->featureValue, majorRadius + minorRadius + GetAx2FeatureValue(axis) + startLen + endLen))
	{
		return actor;
	}

	RemoveActorFromRenderer(actor);
	m_interactorStyle->removePipeline(actor->GetShapeID());

	return createHyperbola(axis, majorRadius, minorRadius, startLen, endLen);
}

Handle(QIVtkSelectionPipeline) MainWindow::UpdateActorPosition(Handle(QIVtkSelectionPipeline) actor, const gp_Pnt& position, bool bAddToCache)
{
	// 判断坐标是否相等
	if (IsNearlyEqual(actor->m_position.X(), position.X()) &&
		IsNearlyEqual(actor->m_position.Y(), position.Y()) &&
		IsNearlyEqual(actor->m_position.Z(), position.Z()))
	{
		return actor;
	}

	// 计算平移向量
	gp_Vec translationVec(
		position.X() - actor->m_position.X(),
		position.Y() - actor->m_position.Y(),
		position.Z() - actor->m_position.Z()
	);
	TopoDS_Shape shape = actor->OccShape();
	// 创建平移变换
	gp_Trsf translation;
	translation.SetTranslation(translationVec);

	BRepBuilderAPI_Transform transformer(shape, translation);

	double featureValue = actor->featureValue;

	// 移除Actor
	RemoveActorFromRenderer(actor);

	Handle(QIVtkSelectionPipeline) newActor =  createBasicUnitActor(transformer.Shape());
	newActor->featureValue = featureValue;
	newActor->m_position = position;

	m_renderWindow->Render();

	if (bAddToCache)
	{
		OnActorConfirmCreate(newActor);
	}

	return newActor;
}

Handle(QIVtkSelectionPipeline) MainWindow::TranslateActor(Handle(QIVtkSelectionPipeline) actor, const gp_Pnt& delta, bool bAddToCache)
{
	// 判断位置是否为0
	if (IsNearlyZero(delta.X()) &&
		IsNearlyZero(delta.Y()) &&
		IsNearlyZero(delta.Z()))
	{
		return actor;
	}

	// 计算平移向量
	gp_Vec translationVec(delta.X(), delta.Y(), delta.Z());
	// 创建平移变换
	gp_Trsf translation;
	translation.SetTranslation(translationVec);

	return TransformActor(actor, translation, bAddToCache);
}

Handle(QIVtkSelectionPipeline) MainWindow::RotateActor(Handle(QIVtkSelectionPipeline) actor, const gp_Ax1& axis, double angle, bool bAddToCache)
{
	// 判断变换是否有效
	if (IsNearlyZero(angle) || 
		(IsNearlyZero(axis.Direction().X()) &&
		IsNearlyZero(axis.Direction().Y()) &&
		IsNearlyZero(axis.Direction().Z())))
	{
		return actor;
	}

	// 创建平移变换
	gp_Trsf translation;
	translation.SetRotation(axis, angle);

	return TransformActor(actor, translation, bAddToCache);
}

Handle(QIVtkSelectionPipeline) MainWindow::TransformActor(Handle(QIVtkSelectionPipeline) actor, const gp_Trsf& transform, bool bAddToCache)
{
	if (!actor)
	{
		return nullptr;
	}

	TopoDS_Shape shape = actor->OccShape();
	BRepBuilderAPI_Transform transformer(shape, transform);

	double featureValue = actor->featureValue;
	gp_XYZ OldPosition = actor->m_position.XYZ();

	// 移除Actor
	RemoveActorFromRenderer(actor);

	Handle(QIVtkSelectionPipeline) newActor = createBasicUnitActor(transformer.Shape());
	newActor->featureValue = featureValue;
	newActor->m_position = gp_Pnt(OldPosition + transform.TranslationPart());

	m_renderWindow->Render();

	if (bAddToCache)
	{
		OnActorConfirmCreate(newActor);
	}

	return newActor;
}

Handle(QIVtkSelectionPipeline) MainWindow::createBasicUnitActor(const TopoDS_Shape& shape, bool bAddToCache)
{
	if (shape.IsNull())
	{
		std::cout << "Warning: Shape is Null" << std::endl;
		return nullptr;
	}

	// 创建一个Pipeline
	Handle(QIVtkSelectionPipeline) actor = new QIVtkSelectionPipeline(shape, QIVtkSelectionPipeline::GetNextShapeID());
	actor->AddToRenderer(m_renderer);

	actor->Actor()->GetProperty()->SetColor(Colors::ActorCreated);
	actor->Actor()->GetProperty()->SetOpacity(0.5f);

	m_interactorStyle->addPipeline(actor, actor->GetShapeID());

	m_renderWindow->Render();

	if (bAddToCache)
	{
		OnActorConfirmCreate(actor);
	}

	return actor;
}

void MainWindow::closeEvent(QCloseEvent* event)
{
	//QApplication::quit();
}

bool MainWindow::CheckCanSubWidget()
{
	if (bHasSubWidget)
	{
		return false;
	}
	bHasSubWidget = true;
	return true;
}

void MainWindow::CubeWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}
	CreateCubeWidget* createCubeWidget = new CreateCubeWidget(this, op, this);
	createCubeWidget->setWindowTitle("创建长方体");
	createCubeWidget->setFixedSize(QSize(340, 320));
	createCubeWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	createCubeWidget->show();
}

void MainWindow::SphereWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}
	CreateSphereWidget* createSphereWidget = new CreateSphereWidget(this, op, this);
	createSphereWidget->setWindowTitle("创建球体");
	createSphereWidget->setFixedSize(QSize(340, 230));
	createSphereWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	createSphereWidget->show();
}

void MainWindow::CylinderWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}
	CreateCylinderWidget* createCylinderWidget = new CreateCylinderWidget(this, op, this);
	createCylinderWidget->setWindowTitle("创建圆柱体");
	createCylinderWidget->setFixedSize(QSize(340, 280));
	createCylinderWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	createCylinderWidget->show();
}

void MainWindow::TorusWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}
	CreateTorusWidget* createTorusWidget = new CreateTorusWidget(this, op, this);
	createTorusWidget->setWindowTitle("创建圆环");
	createTorusWidget->setFixedSize(QSize(340, 280));
	createTorusWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	createTorusWidget->show();
}

void MainWindow::ConeWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}
	CreateConeWidget* createConeWidget = new CreateConeWidget(this, op, this);
	createConeWidget->setWindowTitle("创建圆锥体");
	createConeWidget->setFixedSize(QSize(340, 320));
	createConeWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	createConeWidget->show();
}

void MainWindow::LineWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	CreateLineWidget* createLineWidget = new CreateLineWidget(this, op, this);
	createLineWidget->setWindowTitle("创建直线");
	createLineWidget->setFixedSize(QSize(340, 260));
	createLineWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	createLineWidget->show();
}

void MainWindow::CircleWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	CreatCircleWidget* createCircleWidget = new CreatCircleWidget(this, op, this);
	createCircleWidget->setWindowTitle("创建圆环");
	createCircleWidget->setFixedSize(QSize(340, 340));
	createCircleWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	createCircleWidget->show();
}

void MainWindow::EllipseWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	CreateEllipseWidget* createEllipseWidget = new CreateEllipseWidget(this, op, this);
	createEllipseWidget->setWindowTitle("创建椭圆");
	createEllipseWidget->setFixedSize(QSize(340, 460));
	createEllipseWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	createEllipseWidget->show();
}

void MainWindow::ParabolaWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	CreateParabolaWidget* createParabolaWidget = new CreateParabolaWidget(this, op, this);
	createParabolaWidget->setWindowTitle("创建抛物线");
	createParabolaWidget->setFixedSize(QSize(340, 505));
	createParabolaWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	createParabolaWidget->show();
}

void MainWindow::HyperbolaWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	CreateHyperbolaWidget* createHyperbolaWidget = new CreateHyperbolaWidget(this, op, this);
	createHyperbolaWidget->setWindowTitle("创建双曲线");
	createHyperbolaWidget->setFixedSize(QSize(340, 550));
	createHyperbolaWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	createHyperbolaWidget->show();
}

void MainWindow::BooleanWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	m_renderWindow->Render();
	SetSubWidgetSelected(true);

	BooleanOperationWidget* booleanOperationWidget = new BooleanOperationWidget(this, op, this);
	booleanOperationWidget->setWindowTitle("布尔运算");
	booleanOperationWidget->setFixedSize(QSize(380, 280));
	booleanOperationWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	booleanOperationWidget->show();
}

void MainWindow::TransformWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	TransformOperationWidget* translateOperationWidget = new TransformOperationWidget(this, op, this);
	translateOperationWidget->setWindowTitle("变换运算");
	translateOperationWidget->setFixedSize(QSize(442, 600));
	translateOperationWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	translateOperationWidget->show();
}

void MainWindow::StretchWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	StretchOperationWidget* stretchOperationWidget = new StretchOperationWidget(this, op, this);
	stretchOperationWidget->setWindowTitle("拉伸运算");
	stretchOperationWidget->setFixedSize(QSize(340, 300));
	stretchOperationWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	stretchOperationWidget->show();
}

void MainWindow::RevolveWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	RevolveOperationWidget* revovleOperationWidget = new RevolveOperationWidget(this, op, this);
	revovleOperationWidget->setWindowTitle("旋转运算");
	revovleOperationWidget->setFixedSize(QSize(340, 400));
	revovleOperationWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	revovleOperationWidget->show();
}

void MainWindow::RoundOffWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	RoundOffOperationWidget* roundOffOperationWidget = new RoundOffOperationWidget(this, op, this);
	roundOffOperationWidget->setWindowTitle("倒角运算");
	roundOffOperationWidget->setFixedSize(QSize(340, 220));
	roundOffOperationWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	roundOffOperationWidget->show();

	m_interactorStyle->setSelectionMode(SM_Edge);
}

void MainWindow::HollowWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	HollowOperationWidget* hollowOperationWidget = new HollowOperationWidget(this, op, this);
	hollowOperationWidget->setWindowTitle("抽壳运算");
	hollowOperationWidget->setFixedSize(QSize(340, 220));
	hollowOperationWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	hollowOperationWidget->show();

	m_interactorStyle->setSelectionMode(SM_Face);
}

void MainWindow::FillWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	QFillOperationWidget* fillOperationWidget = new QFillOperationWidget(this, op, this);
	fillOperationWidget->setWindowTitle("填充面");
	fillOperationWidget->setFixedSize(QSize(225, 500));
	fillOperationWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	fillOperationWidget->show();

	m_interactorStyle->setSelectionMode(SM_Edge);
}

void MainWindow::CreateFromObjectWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	QCreateFromObjectOperation* createFromWidget = new QCreateFromObjectOperation(this, op, this);
	createFromWidget->setWindowTitle("Create From Object");
	createFromWidget->setFixedSize(QSize(320, 135));
	createFromWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	createFromWidget->show();
}

void MainWindow::DetachEdgeWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	QDetachEdgeOperation* detachEdgeWidget = new QDetachEdgeOperation(this, op, this);
	detachEdgeWidget->setWindowTitle("Detach Edge");
	detachEdgeWidget->setFixedSize(QSize(320, 135));
	detachEdgeWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	detachEdgeWidget->show();
}

void MainWindow::DetachFaceWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	QDetachFaceOperation* detachFaceWidget = new QDetachFaceOperation(this, op, this);
	detachFaceWidget->setWindowTitle("Detach Edge");
	detachFaceWidget->setFixedSize(QSize(320, 135));
	detachFaceWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	detachFaceWidget->show();
}

void MainWindow::UncoverFaceWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	QUncoverFaceOperation* uncoverFaceWidget = new QUncoverFaceOperation(this, op, this);
	uncoverFaceWidget->setWindowTitle("Uncover Face");
	uncoverFaceWidget->setFixedSize(QSize(320, 135));
	uncoverFaceWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	uncoverFaceWidget->show();
}

void MainWindow::CoverFaceWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	QCoverFaceOperation* coverFaceWidget = new QCoverFaceOperation(this, op, this);
	coverFaceWidget->setWindowTitle("Cover Face");
	coverFaceWidget->setFixedSize(QSize(320, 135));
	coverFaceWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	coverFaceWidget->show();
}

void MainWindow::MoveEdgeWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	QMoveEdgeOperation* moveEdgeWidget = new QMoveEdgeOperation(this, op, this);
	moveEdgeWidget->setWindowTitle("Move Edge");
	moveEdgeWidget->setFixedSize(QSize(340, 160));
	moveEdgeWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	moveEdgeWidget->show();
}

void MainWindow::MoveFaceWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	QMoveFaceOperation* moveFaceWidget = new QMoveFaceOperation(this, op, this);
	moveFaceWidget->setWindowTitle("Move Face");
	moveFaceWidget->setFixedSize(QSize(340, 170));
	moveFaceWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	moveFaceWidget->show();
}

void MainWindow::SectionWidget(ShapeOperation* op)
{
	if (!CheckCanSubWidget())
	{
		return;
	}

	m_interactorStyle->ClearSelectedActors();
	QSectionOpertaion* sectionWidget = new QSectionOpertaion(this, op, this);
	sectionWidget->setWindowTitle("Section");
	sectionWidget->setFixedSize(QSize(340, 170));
	sectionWidget->setWindowFlags(Qt::Tool | Qt::Dialog);
	sectionWidget->show();
}

void MainWindow::redoOperation(ShapeOperation* op)
{
	if (!op)
	{
		return;
	}

	// 有没得优雅的做法啊!
	if (op->m_operationType == EOperationType::Create)
	{
		CreateShapeOperation* createOP = static_cast<CreateShapeOperation*>(op);
		if (createOP->m_featureShape->_featureType == EFeatureType::ArcCircle)
		{
			CircleWidget(op);
		}
		else if (createOP->m_featureShape->_featureType == EFeatureType::Cone)
		{
			ConeWidget(op);
		}
		else if (createOP->m_featureShape->_featureType == EFeatureType::Cylinder)
		{
			CylinderWidget(op);
		}
		else if (createOP->m_featureShape->_featureType == EFeatureType::Ellipse)
		{
			EllipseWidget(op);
		}
		else if (createOP->m_featureShape->_featureType == EFeatureType::Hyperbola)
		{
			HyperbolaWidget(op);
		}
		else if (createOP->m_featureShape->_featureType == EFeatureType::Line)
		{
			LineWidget(op);
		}
		else if (createOP->m_featureShape->_featureType == EFeatureType::Parabola)
		{
			ParabolaWidget(op);
		}
		else if (createOP->m_featureShape->_featureType == EFeatureType::Sphere)
		{
			SphereWidget(op);
		}
		else if (createOP->m_featureShape->_featureType == EFeatureType::Torus)
		{
			TorusWidget(op);
		}
		else if (createOP->m_featureShape->_featureType == EFeatureType::Cube)
		{
			CubeWidget(op);
		}
	}
	else if (op->m_operationType == EOperationType::Boolean)
	{
		BooleanWidget(op);
	}
	else if (op->m_operationType == EOperationType::Delete)
	{
		// nothing to do
	}
	else if (op->m_operationType == EOperationType::Hollow)
	{
		HollowWidget(op);
	}
	else if (op->m_operationType == EOperationType::Transform)
	{
		TransformWidget(op);
	}
	else if (op->m_operationType == EOperationType::Stretch)
	{
		StretchWidget(op);
	}
	else if (op->m_operationType == EOperationType::Revolve)
	{
		RevolveWidget(op);
	}
	else if (op->m_operationType == EOperationType::RoundOff)
	{
		RoundOffWidget(op);
	}
	else if (op->m_operationType == EOperationType::Sketch)
	{
		SketchOperation* sketch = static_cast<SketchOperation*>(op);
		m_sketchManager->CreateSketchByOperation(sketch);
	}
	else if (op->m_operationType == EOperationType::FillFace)
	{
		FillWidget(op);
	}
}

QAction* MainWindow::createAction(const QString& text, const QString& iconurl, const QString& objName)
{
	QAction* act = new QAction(this);
	act->setText(text);
	act->setIcon(QIcon(iconurl));
	act->setObjectName(objName);
	return act;
}

QAction* MainWindow::createAction(const QString& text, const QString& iconurl)
{
	QAction* act = new QAction(this);
	act->setText(text);
	act->setIcon(QIcon(iconurl));
	act->setObjectName(text);
	return act;
}

void MainWindow::SetSubWidgetSelected(bool selected)
{
	bSubWidgetSelected = selected;
}

bool MainWindow::IsSubWidgetSelected()
{
	return bSubWidgetSelected;
}

void MainWindow::RemoveSelectedActor(Handle(QIVtkSelectionPipeline) pipeline)
{
	m_interactorStyle->RemoveSelectedActor(pipeline);
	m_renderWindow->Render();
}

void MainWindow::ClearSelectedActors()
{
	m_interactorStyle->ClearSelectedActors();
	m_renderWindow->Render();
}

TopoDS_Shape MainWindow::BooleanOperation(const TopoDS_Shape& targetShape, const TopoDS_Shape& toolShape, BooleanOP booleanStytle)
{
	TopoDS_Shape resultShape;
	switch (booleanStytle)
	{
	case BooleanOP::Intersect:
		resultShape = BRepAlgoAPI_Common(targetShape, toolShape);
		break;
	case BooleanOP::Subtract:
		resultShape = BRepAlgoAPI_Cut(targetShape, toolShape);
		break;
	case BooleanOP::Union:
		resultShape = BRepAlgoAPI_Fuse(targetShape, toolShape);
		break;
	}
	return resultShape;
}

vtkSmartPointer<vtkActor> MainWindow::CreateTempSphereActor(float radius, const gp_Pnt& position)
{
	// 创建球形数据源
	vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New();
	sphereSource->SetCenter(position.X(), position.Y(), position.Z()); // 设置球心位置
	sphereSource->SetRadius(radius);           // 设置球半径
	sphereSource->Update();

	// 创建球形Mapper
	vtkSmartPointer<vtkPolyDataMapper> sphereMapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	sphereMapper->SetInputConnection(sphereSource->GetOutputPort());

	// 创建球形Actor
	vtkSmartPointer<vtkActor> sphereActor = vtkSmartPointer<vtkActor>::New();
	sphereActor->SetMapper(sphereMapper);

	// 设置Actor的颜色
	sphereActor->GetProperty()->SetColor(1.0, 0.0, .0); // 红色

	m_renderer->AddActor(sphereActor);
	m_renderWindow->Render();

	return sphereActor;
}

void MainWindow::RemoveTempActor(vtkSmartPointer<vtkActor> actor)
{
	m_renderer->RemoveActor(actor);
	m_renderWindow->Render();
}

vtkSmartPointer<vtkActor> MainWindow::CreateTempActor(std::reference_wrapper<const TopoDS_Shape> shape)
{
	vtkSmartPointer<vtkActor> newActor = vtkSmartPointer<vtkActor>::New();
	IVtkOCC_Shape::Handle anIVtkShape = new IVtkOCC_Shape(shape);
	vtkSmartPointer<IVtkTools_ShapeDataSource> _dataSource = vtkSmartPointer<IVtkTools_ShapeDataSource>::New();
	_dataSource->SetShape(anIVtkShape);

	vtkSmartPointer<vtkPolyDataMapper> _mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
	_mapper->SetInputConnection(_dataSource->GetOutputPort());
	newActor->SetMapper(_mapper);
	IVtkTools_ShapeObject::SetShapeSource(_dataSource, newActor);

	newActor->SetPickable(0);
	newActor->SetVisibility(1);
	newActor->GetProperty()->SetColor(1.0, 1.0, 0.0);
	newActor->GetProperty()->SetOpacity(1.f);
	newActor->GetProperty()->SetPointSize(newActor->GetProperty()->GetPointSize() + 2);
	newActor->GetProperty()->SetLineWidth(newActor->GetProperty()->GetLineWidth() + 1);

	m_renderer->AddActor(newActor);
	m_renderWindow->Render();

	
	return newActor;
}

void MainWindow::OnActorConfirmCreate(Handle(QIVtkSelectionPipeline) actor)
{
	actor->CalculateVertexInfo(m_cacheActors);
	m_cacheActors.push_back(actor);
	std::cout << "Actor Nums:" << m_cacheActors.size() << std::endl;
	actor->Actor()->GetProperty()->SetOpacity(1.f);
	actor->Modified();
	m_renderWindow->Render();
}

void MainWindow::RemoveActorFromRenderer(Handle(QIVtkSelectionPipeline) actor)
{
	if (!actor)
	{
		return;
	}

	if (ContainsActor(m_interactorStyle->selectActors, actor))
	{
		RemoveActor(m_interactorStyle->selectActors, actor);
	}

	if (m_interactorStyle->HighlightActor == actor)
	{
		m_interactorStyle->HighlightActor = nullptr;
	}

	m_interactorStyle->removePipeline(actor->GetShapeID());

	actor->RemoveFromRenderer(m_renderer);

	RemoveActor(m_cacheActors, actor);

	m_renderWindow->Render();

	std::cout << "Actor Nums:" << m_cacheActors.size() << std::endl;
}

void MainWindow::RemoveAllActorsFromRenderer()
{
	m_interactorStyle->selectActors.clear();
	m_interactorStyle->HighlightActor = nullptr;

	for (auto& actor : m_cacheActors)
	{
		m_interactorStyle->removePipeline(actor->GetShapeID());
        actor->RemoveFromRenderer(m_renderer);
	}

	m_cacheActors.clear();
	m_renderWindow->Render();
	std::cout << "Actor Nums:0" << std::endl;
}

void MainWindow::SubWidgetClose(bool bIsConfirm)
{
	bHasSubWidget = false;

	if (!bIsConfirm)
	{
		m_historyManager->OnOperationCancel();
	}

	SetSelectionMode(SM_None);
	SetCanMultiSelect(true);
}

Handle(QIVtkSelectionPipeline) MainWindow::GetActorsOuterPipeline(vtkActor* InActor)
{
	// 遍历acheActors
	for (const auto& actor : m_cacheActors)
	{
		if (actor->Actor() == InActor)
		{
			return actor;
		}
	}
	return nullptr;
}

void MainWindow::FlushRender()
{
	if (m_renderWindow)
	{
		m_renderWindow->Render();
	}
}

IVtk_SelectionMode MainWindow::GetSelectionMode() const
{
	return m_interactorStyle->_currentSelectionMode;
}

void MainWindow::SetSelectionMode(IVtk_SelectionMode mode)
{
    m_interactorStyle->setSelectionMode(mode);
}

void MainWindow::SetCanMultiSelect(bool bCanMultiPick)
{
    m_interactorStyle->setCanMultiSelect(bCanMultiPick);
}

void MainWindow::GetVertexPickerTargetPos(bool& bIsPick, gp_Pnt& Pos)
{
	m_interactorStyle->GetVertexPickerTargetPos(bIsPick, Pos);
}

const std::vector<std::reference_wrapper<const TopoDS_Shape>> MainWindow::GetSelectedShapes()
{
	return m_interactorStyle->_selectedShapes;
}

void MainWindow::SetMaxSelectedActors(uint maxSelectedActors)
{
	m_interactorStyle->SetMaxSelectedActors(maxSelectedActors);
}

void MainWindow::ResetMaxSelectedActors()
{
	m_interactorStyle->ResetMaxSelectedActors();
}

const std::vector<Handle(QIVtkSelectionPipeline)>& MainWindow::GetSelectedActors()
{
	return m_interactorStyle->selectActors;
}

std::vector<std::shared_ptr<FeatureShape>> MainWindow::GetCurrentFeatureShapes()
{
	std::vector<std::shared_ptr<FeatureShape>> res;
	for (const auto& actor : m_cacheActors)
	{
        if (actor->m_featureShape)
		{
			res.push_back(actor->m_featureShape);
		}
	}
	return res;
}

void MainWindow::SelectActor(Handle(QIVtkSelectionPipeline) pipeline, bool bClearSelected)
{
	if (!pipeline)
	{
		return;
	}

    m_interactorStyle->SelectActor(pipeline, bClearSelected);
}

Handle(QIVtkSelectionPipeline) MainWindow::GetActorFromFeatureShape(std::shared_ptr<FeatureShape> featureShape)
{
	for (const auto& actor : m_cacheActors)
	{
		if (actor->m_featureShape->IsEqual(*featureShape))
		{
			return actor;
		}
	}
	return nullptr;
}

void MainWindow::onRightClickMenu()
{
	// 创建菜单
	QMenu menu(this);

	if (m_interactorStyle->bIsIn2DMode)
	{
		return;
	}

	// 选中特征
	if (!m_interactorStyle->selectActors.empty())
	{
		menu.addAction(deleteSelectActorsAction);
		menu.addAction(editActorAction);
		menu.addAction(hideSelectAcotrAction);
	}

	menu.addAction(frontView);
	menu.addAction(backView);
    menu.addAction(topView);
    menu.addAction(bottomView);
    menu.addAction(leftView);
    menu.addAction(rightView);
    menu.addAction(positiveTriaxialView);
    menu.addAction(fitView);
	menu.addAction(hideAllActorsAction);
	menu.addAction(showAllActorsAction);

	menu.exec(QCursor::pos());
}
